Many processes that transmit data through input/output ports, across different computing platforms, or across the networks require a large amount of time to execute. These processes may receive requests faster than they can be executed. The traditional solution is to buffer each request in a queue and handle each subsequent request once the preceding request is complete. This solution, however, has drawbacks. For example, if requests are added to the queue faster than they can be serviced, then the memory buffer may become full.
Of course, one could construct a buffer large enough to queue these requests, but this wastes resources in the instances when the requests can be processed as fast as they are received. Moreover, if subsequent requests in a queue make the preceding requests irrelevant (i.e., a first received request updates data, but a later request changes the data back) then the system wastes processing time encoding and decoding both requests and updating the data needlessly.
Another known solution is dividing up the process into a series of processes that may be done in parallel—e.g., multiple threads. This enables incoming requests to be processed while the preceding request is finished. Accordingly, when the preceding request is finished, some amount of processing has already been completed on the subsequent request. Subdividing increases throughput and minimizes the size of the buffer. Nonetheless, subdividing a request may corrupt data that is shared between the multiple processes—e.g., one thread changes data associated with a memory object while a separate thread is currently transmitting that data to an I/O device. Additionally, some processes must be done sequentially which nullifies the benefits of using multiple threads.